﻿/******************************************************************************
 * 【本类功能概述】                                 					      *
 *  版权所有（C）2017-                                           *
 *  保留所有权利。                                                            *
 ******************************************************************************
 *  作者 : <hughjk>
 *  创建时间:2019年5月21日 18:35:25
 *  文件描述:读写文件
 *****************************************************************************/

namespace Util
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    using System.Threading;


    public class FileIO
    {
        #region     存储加载
        //创建读取文件
        public static void CreateLoadPath(string path, string name)
        {
            string Path = path + name;
            CreateSavePath(path);
            if (!File.Exists(Path))//判断文件的存在
            {
                //不存在文件
                File.WriteAllText(Path, string.Empty, Encoding.UTF8);//创建该文件
            }
        }
        //写入文件内容
        public static void Save(string path, string name, string com)
        {
            string Path = path + name;
            CreateSavePath(path);
            File.WriteAllText(Path, com, Encoding.UTF8);
        }

        //写入文件内容
        public static void Save(string path, string name, string com, Encoding e)
        {
            string Path = path + name;
            CreateSavePath(path);
            File.WriteAllText(Path, com, e);
        }
        //写入文件内容
        public static void SaveByte(string path, string name, string com)
        {
            string Path = path + name;
            CreateSavePath(path);
            var b = Encoding.UTF8.GetBytes(com);
            File.WriteAllBytes(Path, b);
        }
        //写入文件内容
        public static void SaveByte(string path, string name, byte[] com)
        {
            string Path = path + name;
            CreateSavePath(path);
            File.WriteAllBytes(Path, com);
        }
        //追加写入文件内容
        public static void AppendSave(string path, string name, string com)
        {
            string Path = path + name;
            CreateSavePath(path);
            File.AppendAllText(Path, com, Encoding.UTF8);
        }

        //读取
        public static StringBuilder Load(string path, string name)
        {
            string Path = path + name;
            StringBuilder sb = new StringBuilder();
            CreateLoadPath(path, name);
            //存在文件
            sb.Append(File.ReadAllText(Path, Encoding.UTF8));
            return sb;
        }
        //读取
        public static byte[] LoadByte(string path, string name)
        {
            string Path = path + name;
            CreateSavePath(path);

            if (!File.Exists(Path))//判断文件的存在
            {
                return null;
            }
            else
            {
                return File.ReadAllBytes(Path);
            }
        }
        //读取全部行
        public static string[] LoadLines(string path, string name, Encoding e)
        {
            string Path = path + name;
            CreateLoadPath(path, name);
            string[] vs = File.ReadAllLines(Path, e);
            return vs;
        }
        #endregion

        #region 遍历目录


        /// <summary>
        /// 遍历文件夹全部对象,包括子文件夹
        /// </summary>
        /// <param name="path">D:\bin\Debug</param>
        /// <param name="fileinfo"></param>
        public static void ForDirectory(string path, Action<FileInfo> fileinfo)
        {
            getDirectory(path, 0, fileinfo);
        }
        /// <summary>
        /// 遍历当前文件夹全部对象 
        /// </summary>
        /// <param name="path">D:\bin\Debug</param>
        /// <param name="fileinfo"></param>
        public static void ForMyDirectory(string path, Action<FileInfo> fileinfo)
        {
            getFileName(path, 0, fileinfo);
        }
        /// <summary>
        /// 获得指定路径下所有文件名
        /// </summary>
        /// <param name="sw">文件写入流</param>
        /// <param name="path">文件写入流</param>
        /// <param name="indent">输出时的缩进量</param>
        private static void getFileName(string path, int indent, Action<FileInfo> fileinfo)
        {
            DirectoryInfo root = new DirectoryInfo(path);
            foreach (FileInfo f in root.GetFiles())
            {
                //debug.log(f.Name);
                fileinfo.Invoke(f);
            }
        }

        /// <summary>
        /// 获得指定路径下所有子目录名
        /// </summary>
        /// <param name="sw">文件写入流</param>
        /// <param name="path">文件夹路径</param>
        /// <param name="indent">输出时的缩进量</param>
        private static void getDirectory(string path, int indent, Action<FileInfo> fileinfo)
        {
            getFileName(path, indent, fileinfo);
            DirectoryInfo root = new DirectoryInfo(path);
            foreach (DirectoryInfo d in root.GetDirectories())
            {
                //sw.WriteLine("文件夹：" + d.Name);
                getDirectory(d.FullName, indent + 1, fileinfo);
            }
        }

        #endregion

        #region 删除指定文件
        //删除指定文件
        public static void Delete(string srcPath)
        {
            if (isLoadPath(srcPath))
            {
                File.Delete(srcPath);      //删除指定文件
            }
        }

        //删除文件夹
        public static void DelectDir(string srcPath)
        {
            try
            {
                DirectoryInfo dir = new DirectoryInfo(srcPath);
                FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();  //返回目录中所有文件和子目录
                foreach (FileSystemInfo i in fileinfo)
                {
                    if (i is DirectoryInfo)            //判断是否文件夹
                    {
                        DirectoryInfo subdir = new DirectoryInfo(i.FullName);
                        subdir.Delete(true);          //删除子目录和文件
                    }
                    else
                    {           //如果 使用了 streamreader 在删除前 必须先关闭流 ，否则无法删除 sr.close();
                        File.Delete(i.FullName);      //删除指定文件
                    }
                }
            }
            catch (Exception e)
            {
                throw;
            }
        }
        #endregion

        #region 路径

        /// <summary>
        /// 检测并创建一个路径
        /// </summary>
        /// <param name="path"></param>
        public static void CreateSavePath(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }
        //判断文件的存在
        public static bool isLoadPath(string path)
        {
            if (!File.Exists(path))//判断文件的存在
            {
                //不存在文件
                return false;
            }
            return true;
        }
        #endregion

        //重命名
        public void Rechristen(string srcPath, string endPath)
        {
            FileInfo fi = new FileInfo(srcPath); //xx/xx/aa.rar
            fi.MoveTo(endPath); //xx/xx/xx.rar
        }

        #region  获取文件信息

        /// <summary>
        /// 获取 MD5 值
        /// </summary>
        /// <returns> 返回MD5值.</returns>
        /// <param name="fileName">文件地址 项目地址   Asstct/t.text </param>
        public static string GetMD5HashFromFile(string path)
        {
            if (!File.Exists(path))
                throw new ArgumentException(string.Format("<{0}>, 不存在", path));
            int bufferSize = 1024 * 16;//自定义缓冲区大小16K
            byte[] buffer = new byte[bufferSize];
            Stream inputStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
            HashAlgorithm hashAlgorithm = new MD5CryptoServiceProvider();
            int readLength = 0;//每次读取长度
            var output = new byte[bufferSize];
            while ((readLength = inputStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                //计算MD5
                hashAlgorithm.TransformBlock(buffer, 0, readLength, output, 0);
            }
            //完成最后计算，必须调用(由于上一部循环已经完成所有运算，所以调用此方法时后面的两个参数都为0)
            hashAlgorithm.TransformFinalBlock(buffer, 0, 0);
            string md5 = BitConverter.ToString(hashAlgorithm.Hash);
            hashAlgorithm.Clear();
            inputStream.Close();
            md5 = md5.Replace("-", "");
            return md5;
        }
        //获取文件文件夹大小
        public static long FileSize(string filePath)
        {
            long temp = 0;

            //判断当前路径所指向的是否为文件
            if (File.Exists(filePath) == false)
            {
                string[] str1 = Directory.GetFileSystemEntries(filePath);
                foreach (string s1 in str1)
                {
                    temp += FileSize(s1);
                }
            }
            else
            {
                //定义一个FileInfo对象,使之与filePath所指向的文件向关联,

                //以获取其大小
                FileInfo fileInfo = new FileInfo(filePath);
                return fileInfo.Length;
            }
            return temp;
        }
        #endregion

        #region 打开文件夹

        //打开一个Txt文件 
        public void WinOperTxt(string path)
        {
            //System.Diagnostics.Process.Start("notepad.exe ", "Log.txt");
            Process.Start("notepad.exe ", path);
        }


        /// <summary>
        /// 打开文件夹 @"D:/ZP/Test";
        /// </summary>
        /// <param name="path"></param>
        public static void OpenDirectory(string path)
        {
            // 新开线程防止锁死
            Thread newThread = new Thread(new ParameterizedThreadStart(CmdOpenDirectory));
            newThread.Start(path);
        }

        private static void CmdOpenDirectory(object obj)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/c start " + obj.ToString();
            UnityEngine.Debug.Log(p.StartInfo.Arguments);
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();

            p.WaitForExit();
            p.Close();
        }
        #endregion

    }
}